package app

import (
	"bytes"
	"kubeInstall/pkg/logger"
	"strings"
	"text/template"
)

const TemplateText = string(`apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: {{.Version}}
controlPlaneEndpoint: "{{.ApiServer}}:6443"
imageRepository: {{.RepoName}}
clusterName: {{.ClusterName}}
networking:
  dnsDomain: {{.ClusterName}}
  podSubnet: {{.PodCIDR}}
  serviceSubnet: {{.SvcCIDR}}
dns:
  type: CoreDNS
apiServer:
  certSANs:
  - 127.0.0.1
  - {{.ApiServer}}
  {{range .Masters -}}
  - {{.}}
  {{end -}}
  - {{.VIP}}
  extraArgs:
    feature-gates: TTLAfterFinished=true
  extraVolumes:
  - name: etc-pki-tls
    hostPath: /etc/pki/tls
    mountPath: /etc/pki/tls
    readOnly: true
  - name: etc-pki-ca-trust
    hostPath: /etc/pki/ca-trust
    mountPath: /etc/pki/ca-trust
    readOnly: true
  - name: localtime
    hostPath: /etc/localtime
    mountPath: /etc/localtime
    readOnly: true
    pathType: File
scheduler:
  extraArgs:
    feature-gates: TTLAfterFinished=true,CSINodeInfo=true,VolumeSnapshotDataSource=true,ExpandCSIVolumes=true,RotateKubeletClientCertificate=true
  extraVolumes:
  - name: localtime
    hostPath: /etc/localtime
    mountPath: /etc/localtime
    readOnly: true
    pathType: File
controllerManager:
  extraArgs:
    feature-gates: TTLAfterFinished=true,CSINodeInfo=true,VolumeSnapshotDataSource=true,ExpandCSIVolumes=true,RotateKubeletClientCertificate=true
  extraVolumes:
  - name: localtime
    hostPath: /etc/localtime
    mountPath: /etc/localtime
    readOnly: true
    pathType: File
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: {{.ApiServer}}
  bindPort: 6443
nodeRegistration:
  name: master
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
  criSocket: /var/run/dockershim.sock
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: {{.CgroupDriver}}
clusterDomain: {{.ClusterName}}
containerLogMaxFiles: 5
clusterDNS:
- 169.254.25.10
containerLogMaxSize: 10Mi
maxPods: {{.MaxPodNum}}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
clientConnection:
 acceptContentTypes: 
 burst: 10
 contentType: application/vnd.kubernetes.protobuf
 kubeconfig: 
 qps: 5
clusterCIDR: {{.PodCIDR}}
configSyncPeriod: 15m0s
conntrack:
 maxPerCore: 32768
 min: 131072
 tcpCloseWaitTimeout: 1h0m0s
 tcpEstablishedTimeout: 24h0m0s
enableProfiling: False
healthzBindAddress: 0.0.0.0:10256
iptables:
 masqueradeAll: False
 masqueradeBit: 14
 minSyncPeriod: 0s
 syncPeriod: 30s
mode: "{{.ProxyMode}}"
metricsBindAddress: 0.0.0.0:10249
ipvs:
  minSyncPeriod: 0s
  scheduler: rr
  syncPeriod: 30s
  strictARP: False
  excludeCIDRs: 
  - "{{.VIP}}/32"`)

type KubeAdmJoinOpts struct {
	Token                    string
	DiscoveryTokenCaCertHash string
	MasterIP                 string
	CertificateKey           string
}

type KubeAdmConfig struct {
	MasterIPs         []string
	VIP               string
	Version           string
	ApiServer         string
	PodCIDR           string
	SvcCIDR           string
	RepoName          string
	ProxyMode         string
	MaxPodNum         int
	CgroupDriver      string
	ClusterName       string
/*	NetworkPlugin     string
	StoragePluginType string*/
}

func LoadKubeAdmContent(r *KubeAdmConfig) []byte {
	var sb strings.Builder
	sb.Write([]byte(TemplateText))

	tmpl, err := template.New("text").Parse(sb.String())
	defer func() {
		if r := recover(); r != nil {
			logger.Error("template parse failed:", err)
		}
	}()
	if err != nil {
		panic(1)
	}
	var envMap = make(map[string]interface{})
	envMap["VIP"] = r.VIP
	envMap["Masters"] = r.MasterIPs
	envMap["Version"] = r.Version
	envMap["ApiServer"] = r.ApiServer
	envMap["PodCIDR"] = r.PodCIDR
	envMap["SvcCIDR"] = r.SvcCIDR
	envMap["RepoName"] = r.RepoName
	envMap["ClusterName"] = r.ClusterName
	envMap["ProxyMode"] = r.ProxyMode
	envMap["MaxPodNum"] = r.MaxPodNum
	if r.CgroupDriver == "" {
		envMap["CgroupDriver"] = "cgroupfs"
	}
	envMap["CgroupDriver"] = r.CgroupDriver
	var buffer bytes.Buffer
	_ = tmpl.Execute(&buffer, envMap)
	return buffer.Bytes()
}

func GetKubeadmConfig(r *KubeAdmConfig) string {

	return string(LoadKubeAdmContent(r))

}
